﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;

namespace BasePlatformNetAgent
{
	public class BytesConvert
	{
		public static byte[] StructToBytes(object structObj)
		{
			int size = Marshal.SizeOf(structObj);
			IntPtr buffer = Marshal.AllocHGlobal(size);
			try
			{
				Marshal.StructureToPtr(structObj, buffer, false);
				byte[] bytes = new byte[size];
				Marshal.Copy(buffer, bytes, 0, size);
				return bytes;
			}
			finally
			{
				Marshal.FreeHGlobal(buffer);
			}

		}

		public static object BytesToStruct(byte[] bytes, Type strcutType)
		{
			int size = Marshal.SizeOf(strcutType);
			IntPtr buffer = Marshal.AllocHGlobal(size);
			try
			{
				Marshal.Copy(bytes, 0, buffer, size);
				return Marshal.PtrToStructure(buffer, strcutType);
			}
			finally
			{
				Marshal.FreeHGlobal(buffer);
			}
		}

		public static byte[] ObjectToBytes<T>(T obj)
		{
			try
			{
				using (MemoryStream ms = new MemoryStream())
				{
					System.Runtime.Serialization.IFormatter formatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
					formatter.Serialize(ms, obj);
					return ms.GetBuffer();
				}
			}
			catch (Exception)
			{
				return null;
			}
		}

		public static byte[] ObjectToBytes<T>(T obj, bool isCompress)
		{
			if (!isCompress)
			{
				return ObjectToBytes<T>(obj);
			}
			else
			{
				try
				{
					using (MemoryStream ms = new MemoryStream())
					{
						System.Runtime.Serialization.IFormatter formatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
						formatter.Serialize(ms, obj);
						MemoryStream tempms = new MemoryStream();
						System.IO.Compression.GZipStream gzs = new System.IO.Compression.GZipStream(tempms, System.IO.Compression.CompressionMode.Compress, true);
						byte[] arrByte = ms.GetBuffer();
						gzs.Write(arrByte, 0, arrByte.Length);
						gzs.Close();
						gzs.Dispose();
						return tempms.ToArray();
					}
				}
				catch (Exception ex)
				{
					throw ex;
				}
			}
		}

		public static T BytesToObject<T>(byte[] arrBytes)
		{
			try
			{
				using (MemoryStream ms = new MemoryStream(arrBytes))
				{
					System.Runtime.Serialization.IFormatter formatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
					if (ms != null)
					{
						object obj = formatter.Deserialize(ms);
						T t = (T)obj;
						return t;
					}
					else
					{
						return default(T);
					}
				}
			}
			catch (Exception)
			{
				return default(T);
			}
		}

		// 将 byte 数组转换为对象, 如果数据是压缩数据, 那么 isCompress 必须为 true
		public static T BytesToObject<T>(byte[] arrBytes, bool isCompress)
		{
			if (!isCompress)
			{
				return BytesToObject<T>(arrBytes);
			}
			else
			{
				try
				{
					using (MemoryStream ms = new MemoryStream(arrBytes))
					{
						System.Runtime.Serialization.IFormatter formatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
						object obj = formatter.Deserialize(ms);
						T t = (T)obj;
						return t;
					}
				}
				catch (Exception ex)
				{
					throw ex;
				}
			}
		}
	}
}
